go_bunzee

Boosting Performance in Next | 매거진에 참여하세요

questTypeString.01quest1SubTypeString.04
publish_date : 25.07.31

Boosting Performance in Next

#Next #Node #Perform #Slow #Improve #Tips

content_guide

10 Practical Tips for Boosting Performance in Node.js & Next.js

From smart DB tricks to frontend lazy-loading — these are the real-world optimizations that made our stack fly.

When your site suddenly feels sluggish or your API response times creep up without warning, it’s easy to assume your infrastructure is to blame.

But more often than not, the bottlenecks lie in your code — how you fetch data, how you load assets, and how your app communicates across the stack.

Here are 10 field-tested performance tips we’ve applied to real-world projects using Next.js, React, and Node.js (Express).

1. Avoid Real-Time Aggregate Queries — They're Silent Killers

Functions like COUNT,SUM,AVG

on large tables can crush your database if called frequently, especially on high-traffic pages.

Instead:

  • Pre-calculate via scheduled cron jobs or worker queues

  • Cache the results in Redis or a “summary” DB table

  • Display cached results by default, with a “refresh” button if needed

  • Only run real-time calculations on detail views, not overview pages

Pro tip: If your pages are slowly degrading over time, check your aggregate queries first.

2. next/image Isn’t Always Fast

Next.js's next/image component performs real-time resizing on the server. While it’s powerful, it introduces overhead

— especially for simple static images or serverless environments.

Use it wisely:

Scenario

Recommended Strategy

CDN-hosted static images

Use raw <img loading="lazy">

Internal uploads or resizing needed

Use with loadernext/image

FaaS-based SSR or remote URLs

Avoid next/image

3. Use useInView Instead of Premature Fetchin

Many developers assumeuseEffect() waits until a component is visible to run

— but it doesn’t. It fires as soon as the component is mounted.

For smarter network usage, use react-intersection-observer

to trigger data fetch only when the user scrolls into view.

const { ref, inView } = useInView({ rootMargin: '400px', triggerOnce: true });  
useEffect(() => {   if (inView) fetchData(); }, [inView]); 

4. Replace Pagination with Infinite Scroll

Don’t load 100 items at once. Instead, use infinite scroll to improve perceived performance and user engagement.

What to handle:

  • Prevent duplicate fetches with useRef or throttling

  • Free up memory for unmounted elements if possible

  • Keep UX consistent by showing loading indicators

5. Use dynamic() to Delay Component Loading

In Next.js, if a component doesn’t need SSR, you can dynamically import it to reduce your initial JavaScript bundle size.

const MapModal = dynamic(() => import('../MapModal'), { ssr: false }); 

Use this for modals, tooltips, or sections far down the page — anything not needed at first paint.

6. Avoid Global Middleware in Express

Every middleware runs on every route unless scoped. For API performance, keep global middleware to a minimum.

Better approach:

app.use('/api/private', authMiddleware); // scoped app.get('/robots.txt', (req, res) => res.send('User-agent: *\nDisallow:')); 

7. Convert All Images to webp format

Heavy .png and .jpg

uploads slow down pages — especially on mobile.

Automate conversion and compression using

sharp(imageBuffer)   .resize({ width: 800 })   .toFormat('webp')   .toBuffer() 

Then store it in S3 and serve via CloudFront for CDN acceleration.

8. Embrace HTTP/2 + CDN + Smart Caching

HTTP/2 brings faster multiplexing and header compression — but your origin (like S3) might not support it natively.

Solution:

  • Use CloudFront in front of S3

  • Rewire URLs on the fly:

function rewriteToCDN(url) {   return url.replace('https://bucket.s3.region.amazonaws.com', 'https://cdn.example.com'); } 
  • Enable aggressive caching headers for static assets

9. Manage DB Connection Pools Smartly

Too many open connections = memory bloat. Too few = slow queries.

PostgreSQL example using

const pool = new Pool({   max: 10,   idleTimeoutMillis: 30000, }); 

Always tune this based on traffic and load testing.

10. Batch Your Async Operations with Promise.all

Calling await in series increases I/O wait time.

Bad:

await saveUser(); await sendEmail(); 

Good:

await Promise.all([saveUser(), sendEmail()]); 
use map + Promise.all() instead of forEach 

Final Thoughts

Performance isn’t a one-time tweak — it’s a discipline.

You don’t need to implement all 10 tips at once. Start by identifying your bottlenecks, then layer in the relevant optimizations.

Every millisecond you shave off adds up to better UX, lower infra costs, and a happier dev team.